第2章 Cで使える複素数型
普段 C でプログラムを書いている人でも知らない人もいると思いますが、最 近の GCC(Gnu C Compiler)は複素数データ型を扱えるようになっています。 X68k で複素数データ型を扱える GCC としては、Charlie 版 GCC があります。 これは GCC2 と呼ばれているもので、激光電脳倶楽部 Vol.1 に収録されていま す。 X68k 用の GCC として古くから親しまれている真里子版 GCC は、ベースにな っている本家の GCC のバージョンが古いため、複素数データ型を扱うことはで きませんので注意して下さい。 一般的には、真里子版 GCC は 68000 用の最適化が優れており、GCC2 は -m68030 -m68881 や -m68040 を指定して 68030〜68060 用にコンパイルすると 効率の良いコードを出力するようです。用途に応じて使い分けてもよいかも知れ ません。 ●複素数データ型の宣言 複素数データ型を宣言するには、任意の整数データ型または浮動小数点数デー タ型の宣言の手前に __complex__ と書きます。複素数の実数部と虚数部はそれ ぞれ __complex__ の後に続いている整数データ型または浮動小数点数データ型 の数値になります。 ・複素数データ型の宣言の例 __complex__ double z; z は実数部と虚数部がそれぞれ double の複素数。 __complex__ float z; z は実数部と虚数部がそれぞれ float の複素数。 __complex__ int z; z は実数部と虚数部がそれぞれ int の複素数。 __complex__ short z; z は実数部と虚数部がそれぞれ short の複素数。 ●複素数データ型の定数の書き方 複素数データ型の定数を書くときは、接尾辞 i または j を使います。どちら を使っても同じ意味になります。数学系の人は i、電気系の人は j を使うこと が多いですね。接尾辞 i または j を付けた定数は虚数部になるので、定数の実 数部に定数の虚数部を加えることで複素数データ型の定数を書くことができます。 ・複素数データ型の定数の例 1i __complex__ int の定数。実数部は int の 0、虚数部は int の 1。 0.1fi __complex__ float の定数。実数部は float の 0.0、虚数部 は float の 0.1。 -0.5+0.8660254i __complex__ double の定数。実数部は double の -0.5、虚数 部は double の 0.8660254。 ●実数部と虚数部の抽出 複素数データ型の数値から実数部や虚数部を取り出したいときは、複素数デー タ型の式の手前に __real__ または __imag__ と書きます。複素数データ型の数 値から、__real__ は実数部を、__imag__ は虚数部を取り出します。 ・複素数データ型の式から実数部と虚数部を取り出す例 __real__ (1+2i) int の 1 になります。 __imag__ (1+2i) int の 2 になります。 ●実数部と虚数部の更新 複素数データ型の式が、左辺式にできるもの(代入演算子の左辺に書ける式) であれば、その手前に __real__ または __imag__ を付けた式も左辺式になるこ とができます。つまり、複素数データ型の式の実数部または虚数部を別々に更新 することができます。 ・複素数データ型の実数部と虚数部を別々に更新する例 __complex__ double z; double re, im; : __real__ z = re; __imag__ z = im; z の実数部に re を、虚数部に im を入れます。 ●共役複素数 単項前置演算子 ‾ は普段は整数に対するビット単位の論理否定演算子として 使わますが、複素数データ型の値に対しては共役複素数を求める演算子として働 きます。 ・共役複素数を求める例 __complex__ double z, conj_z; : conj_z = ‾z; conj_z の値は z の値の共役複素数(虚数部の符号を反転した もの)になります。 ●簡単なサンプルプログラム(1) ┌──────────────────────── 1│#include <stdio.h> 2│ 3│void foo(__complex__ double z) 4│{ 5│ printf("%.14g%+.14gi¥n", __real__ z, __imag__ z); 6│} 7│ 8│void main(int argc, char *argv[]) 9│{ 10│ foo(1+2i); 11│} これを GCC2 でコンパイルして実行すると、 ┌──────────────────────── │1+2i と表示されます。 複素数を表示するときは虚数部の符号を強制的に表示させるために %+〜 を使 うと便利です。 ●簡単なサンプルプログラム(2) ┌──────────────────────── 1│#include <stdio.h> 2│ 3│void main(int argc, char *argv[]) 4│{ 5│ printf("%d¥n", sizeof(typeof(0.5i))); 6│} これを GCC2 でコンパイルして実行すると、 ┌──────────────────────── │16 と表示されます。 typeof(〜) はデータの型を返す演算子です。0.5i の型は __complex__ double なので、sizeof(double)==8 の 2 倍(実数部のサイズと虚数部のサイズ を合わせた値)の 16 が返ります。 (EOF)